<template>
  <div>
    <div id="chart" style="width: 100%;height: 800px;"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import ecStat from 'echarts-stat'


export default {
  name: 'FourQuadrantScatter',
  data() {
    return {
      chart: null,
      posMap: {}
    }
  },
  mounted() {
    this.resizeChart()
  },
  methods: {
    resizeChart() {
      let chartDom = document.getElementById('chart')
      let myChart = echarts.init(chartDom)
      let option
      let colorList = [
        '#d32c1f',
        '#0872c8',
        '#56ae57',
        '#b2996e',
        '#894585',
        '#388004',
        '#efb435',
        '#0c06f7',
        '#3778bf',
        '#1f6357',
        '#0cb577',
        '#ff0789',
        '#ff63e9',
        '#430541',
        '#ad900d',
        '#ff5733',
        '#f6688e',
        '#014600',
        '#0c1793',
        '#a50055',
        '#ad03de',
        '#0165fc',
        '#f97306'
      ]
      echarts.registerTransform(ecStat.transform.clustering)
      const data = [
          ['北京市', 95.5, 100],
          ['天津市', 96.6, 130],
          ['石家庄市', 97.5, 143],
          ['太原市', 98.5, 150],
          ['呼和浩特市', 97.5, 160],
          ['沈阳市', 98.5, 155],
          ['长春市', 95.5, 145],
          ['哈尔滨市', 95.5, 150],
          ['上海市', 97.5, 120],
          ['南京市', 98.5, 110],
          ['杭州市', 94.1, 101],
          ['合肥市', 97.5, 130],
          ['福州市', 95.5, 142],
          ['南昌市', 96.1, 150],
          ['济南市', 95.5, 160],
          ['郑州市', 96.3, 150],
          ['武汉市', 94.5, 138],
          ['长沙市', 96.8, 130],
          ['广州市', 97.5, 165],
          ['南宁市', 96.2, 110],
          ['海口市', 96.7, 170]
        ];
      let xMin = Math.min(...data.map((e) => Math.floor(e[1] || 0)));
      let xMax = Math.max(...data.map((e) => Math.ceil(e[1] || 0)));
      let yMin = Math.min(...data.map((e) => Math.floor(e[2] || 0)));
      let yMax = Math.max(...data.map((e) => Math.ceil(e[2] || 0)));

      let eleList = [
        { name: '第一象限说明', left: 80, top: 80 },
        { name: '第二象限说明', right: 80, top: 80 },
        { name: '第三象限说明', left: 80, bottom: 80 },
        { name: '第四象限说明', right: 80, bottom: 80 }
      ]
      option = {
        title: {
          show: true,
          text: '图例名称',
          left: 'left'
        },
        dataset: [{ source: data }],
        tooltip: {
          position: 'top',
          confine: true
        },
        grid: {
          show: true,
          borderWidth: 2,
          borderColor: '#B2D0EA',
          left: 80,
          top: 80,
          right: 80,
          bottom: 80
        },
        xAxis: {
          name: 'x轴说明',
          nameLocation: 'center',
          type: 'value',
          nameTextStyle: { padding: [0, 0, 50, 0] },
          min: xMin,
          max: xMax,
          inverse: false,
          position: 'top',
          axisLabel: {
            fontSize: 11,
            rotate: 60
          },
          axisLine: { show: false },
          axisTick: { show: false },
          splitLine: { show: false }
        },
        yAxis: {
          name: 'y轴说明',
          nameLocation: 'center',
          type: 'value',
          nameTextStyle: { padding: [0, 0, 50, 0] },
          min: yMin,
          max: yMax,
          inverse: true,
          axisLabel: { fontSize: 11 },
          axisLine: { show: false },
          axisTick: { show: false },
          splitLine: { show: false }
        },
        // 四个角落的文字描述
        graphic: {
          elements: eleList.map((item) => ({
            type: 'text',
            z: 1,
            left: item.left,
            right: item.right,
            top: item.top,
            bottom: item.bottom,
            style: {
              text: `{name|${item.name}}`,
              fill: '#fff',
              rich: {
                name: {
                  fontSize: 16,
                  backgroundColor: '#5B9BD5',
                  borderColor: '#000',
                  borderWidth: 1,
                  padding: 5
                }
              }
            },
            tooltip: {
              formatter: function () {
                return item.name
              }
            }
          }))
        },
        // 地市打点
        series: [
          {
            z: 2,
            type: 'scatter',
            // 调整区域颜色
            markArea: {
              itemStyle: { // 全局的
                normal: { color: '#ff3333' }
              },
              data: this.handleColor(xMax, xMin, yMax, yMin)
            },
            tooltip: {
              formatter: function (params) {
                console.log(params);
                return `${params.data[0]}：${params.data[2]}，${params.data[1]}`;
              }
            },
            encode: { x: 1, y: 2 },
            symbolSize: 8,
            datasetIndex: 1,
            data: data,
            itemStyle: {
              color: function(e) {
                const color = colorList[e.dataIndex]
                return color
              },
              opacity: 1,
              borderWidth: 1
            },
            label: {
              color: 'inherit',
              show: true,
              position: 'right',
              formatter: '{@value}', // 点旁边显示label，这里使用name: '横坐标'这样写也可以，鼠标移入出现提示。
              backgroundColor: '#eee', // 标签背景颜色
              borderColor: '#777', // 外层边框颜色
              borderWidth: 1, // 外层边框宽度
              borderRadius: 4, // 外层边框圆角
              padding: [2, 2, 2, 2]
            },
            labelLine: {
              show: true, // 是否显示视觉引导线
              length: 6, // 视觉引导线的长度
              length2: 4, // 视觉引导线第二段的长度
              smooth: true, // 是否平滑曲线显示
              lineStyle: { width: 1, type: 'solid' }
            },
            markLine: {
              symbol: ['none', 'none'],
              label: { show: true },
              lineStyle: {
                width: 2,
                type: 'solid',
                color: '#ccc'
              },
              tooltip: { show: false },
              data: [
                {
                  xAxis: (xMax + xMin) / 2
                },
                {
                  yAxis: (yMax + yMin) / 2
                }
              ]
            },
            // 避免 label 重叠，重新进行画布划分
            labelLayout: (params) => {
              let dPos = this.getDeltaPos(params)
              return { dx: dPos.dx, dy: dPos.dy }
            }
          }
        ],
        animation: false,
        // 图表保存为png
        toolbox: { feature: { saveAsImage: { show: true } } }
      }
      option && myChart.setOption(option)
      let echart = null
      if (chartDom !== null) {
        echart = echarts.getInstanceByDom(chartDom)
      }
      const base64Str = echart.getDataURL({
        type: 'png',
        pixelRatio: 2, // 导出的图片分辨率比例，默认为 1
        // 导出的图片背景色，默认使用 option 里的 backgroundColor
        backgroundColor: '#fff'
      })
      console.log('图片转成base64', base64Str);
      
    },
    handleColor(xMax, xMin, yMax, yMin) {
      // 当x、y的inverse 的true、false轴进行翻转时，可以通过转换颜色达到四个象限的颜色固定
      let list = []
      let initList = [
        [
          {
            yAxis: Math.round((yMax + yMin) / 2),
            xAxis: Math.round((xMax + xMin) / 2),
            itemStyle: { color: 'red', opacity: 0.3 } // 背景色透明度为0.3
          }, {}
        ],
        [
          {
            yAxis: Math.round((yMax + yMin) / 2),
            xAxis: Math.round((xMax + xMin) / 2),
            itemStyle: { color: 'blue', opacity: 0.3 }
          },
          { xAxis: xMin }
        ],
        [
          { itemStyle: { color: 'yellow', opacity: 0.3 } },
          { coord: [Math.round((xMax + xMin) / 2), Math.round((yMax + yMin) / 2)] }

        ],
        [
          {
            yAxis: Math.round((yMax + yMin) / 2),
            xAxis: Math.round((xMax + xMin) / 2),
            itemStyle: { color: 'pink', opacity: 0.3 }
          },
          { yAxis: yMin }
        ]
      ]
      for (let index = 0; index < 4; index++) {
          list[index] = initList[index]
      }
      return list
    },
    getDeltaPos(params) {
      let rect = params.rect
      let labelWidth = 30
      let labelHeight = 27
      let rectX = rect.x
      let rectY = rect.y
      let gridx = Math.floor(rectX / labelWidth)
      let gridy = Math.floor(rectY / labelHeight)
      let currCell = [gridx, gridy]

      // 如果格子已被占，循环查找
      let currPos = []
      let increaseArr = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1], [1, 0]]
      // 将显示区域划分成一个个定宽和定高的区域
      // 将标签放在离它最近的区域
      // 如果最近的那格没有，向周围九宫格上面找
      // 找到一个没有放过的,分配给它，然后得出一个偏移量

      let found = false
      // 如果格子已被占，循环查找
      if (this.posMap[currCell[0] + '-' + currCell[1]]) {
        while (!found) {
          for (let i = 0; i < increaseArr.length; i++) {
            currCell[0] = currCell[0] + increaseArr[i][0]
            currCell[1] = currCell[1] + increaseArr[i][1]
            if (!this.posMap[currCell[0] + '-' + currCell[1]]) {
              found = true
              this.posMap[currCell[0] + '-' + currCell[1]] = params.text
              currPos = [currCell[0] * labelWidth, currCell[1] * labelHeight]
              break
            }
          }
          if (found) {
            break
          }
        }
      } else {
        // 如果格子没有被占，就它了
        this.posMap[gridx + '-' + gridy] = params.text
      }
      currPos = [currCell[0] * labelWidth, currCell[1] * labelHeight]
      let deltaPos = {
        dx: currPos[0] - rect.x,
        dy: currPos[1] - rect.y
      }

      return deltaPos
    }
  }
}

</script>